home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
PC World Interactive 7
/
PC World Interactive 7.iso
/
program
/
cprog.EXE
/
CC_1.ZIP
/
CC51.C
< prev
next >
Wrap
Text File
|
1990-11-22
|
18KB
|
666 lines
/*
** peephole optimizer
**
** basically a simple text replacement processor
*/
char nooptimize = 0; /* this flag disables optimization if set (by debug) */
peephole(ptr) char *ptr; {
while(*ptr) {
char *ptr1;
ptr1 = ptr; /* save for later compare */
/*
** if optimization is disabled, skip everything
** all patterns start with tab, so look for one
*/
while(*ptr && (*ptr != '\t'|| nooptimize)) cout(*ptr++,output);
if(streq(ptr, "\tLEA AX,[BP]")) ptr = optim1(ptr, 12);
if(streq(ptr, "\tMOV AX,1\n")) ptr = optim3(ptr, 10);
if(streq(ptr, "\tMOV AX,")) ptr = optim4(ptr, 8);
if(streq(ptr, "\tPUSH AX\n\tMOV AX,")) ptr = optim5(ptr, 17);
if(streq(ptr, "\tPUSH AX\n\tLEA AX,[BP]")) ptr = optim6(ptr, 21);
if(streq(ptr, "\tMOV BX,DX\n\tPOP BX\n")) ptr = optim7(ptr, 19);
if(streq(ptr, "\tMOV BX,")) ptr = optim8(ptr, 8);
if(streq(ptr, "\tJNZ $+5\n")) ptr = optim9(ptr+9, "JNZ $+");
if(streq(ptr, "\tJZ $+5\n")) ptr = optim9(ptr+8, "JZ $+");
/* additional optimizing logic goes here */
if(ptr == ptr1) cout(*ptr++, output);
}
}
/*
** optimize strings beginning "\tLEA AX,[BP]"
*/
optim1(ptr, bump) char *ptr; int bump; {
char offset[20], *ptr1, *ptr2;
ptr1 = ptr + bump; /* skip text already recognized */
ptr2 = offset;
while((*ptr2++ = *ptr1++) > ' ') ++bump; /* save offset from LEA */
*--ptr2 = 0;
++bump;
ptr2 = ptr; /* save for compare */
if(streq(ptr1, "\tMOV BX,AX\n\tMOV SI,AX\n\tMOV AX,[SI]\n"))
ptr = optim11(ptr, bump+35, offset);
else if(streq(ptr1, "\tMOV SI,AX\n\tMOV AX,[SI]\n"))
ptr = optim12(ptr, bump+24, offset);
else if(streq(ptr1, "\tMOV SI,AX\n\tMOV AL,[SI]\n")) {
ot("MOV AL,[BP]");
outstr(offset);
outstr(" ;optim1 - 1");
nl();
ptr = ptr1 + 24;
}
else if(streq(ptr1, "\tPUSH AX\n\tLEA AX,[BP]"))
ptr = optim13(ptr, bump+21, offset);
else if(streq(ptr1, "\tPUSH AX\n\tMOV AX,"))
ptr = optim14(ptr, bump+17, offset);
else if(streq(ptr1, "\tPUSH AX\n\tMOV SI,AX\n"))
ptr = optim15(ptr, bump+20, offset);
return ptr;
}
/*
** optimize strings beginning
** "\tLEA AX,[BP]xxxx\n\tMOV BX,AX\n\tMOV SI,AX\n\tMOV AX,[SI]\n"
*/
optim11(ptr, bump, offset) char *ptr, offset[]; int bump; {
char *ptr1, *ptr2;
ptr1 = ptr + bump; /* skip text already recognized */
ptr2 = ptr; /* save for compare */
if(streq(ptr1, "\tINC AX\n\tMOV [BX],AX\n"))
ptr = optim111(ptr, bump+21, offset);
else if(streq(ptr1, "\tDEC AX\n\tMOV [BX],AX\n"))
ptr = optim112(ptr, bump+21, offset);
return ptr;
}
/*
** optimize strings beginning
** "\tLEA AX,[BP]xxxx\n\tMOV BX,AX\n\tMOV SI,AX\n\tMOV AX,[SI]\n"
** "\tINC AX\n\tMOV [BX],AX\n"
*/
optim111(ptr, bump, offset) char *ptr, offset[]; int bump; {
char *ptr1, *ptr2;
ptr1 = ptr + bump; /* skip text already recognized */
ptr2 = ptr; /* save for compare */
if(streq(ptr1, "\tDEC AX\n\tMOV SI,AX\n\tMOV AL,[SI]\n")) {
if(ptr1[32]) { /* if not end of expression */
ot("MOV BX,[BP]");
outstr(offset);
nl();
ot("INC WORD PTR [BP]");
outstr(offset);
nl();
ol("MOV AL,[BX] ;optim111 - 1");
ptr = ptr1 + 32;
}
else
ptr = opti1111(ptr, bump+32, offset);
}
else if(streq(ptr1, "\tDEC AX\n")) {
if(ptr1[8]) { /* if not end of expression */
ot("MOV AX,[BP]");
outstr(offset);
nl();
ot("INC WORD PTR [BP]");
outstr(offset);
outstr(" ;optim111 - 2");
nl();
ptr = ptr1 + 8;
}
else
ptr = opti1111(ptr, bump+8, offset);
}
else if(streq(ptr1, "\tMOV SI,AX\n\tMOV AL,[SI]\n")) {
if(ptr1[8]) { /* if not end of expression */
ot("INC WORD PTR [BP]");
outstr(offset);
nl();
ot("MOV BX,[BP]");
outstr(offset);
nl();
ol("MOV AL,[BX] ;optim111 - 3");
ptr = ptr1 + 24;
}
else
ptr = opti1111(ptr, bump+24, offset);
}
else {
if(ptr1[0]) { /* if not end of expression */
ot("INC WORD PTR [BP]");
outstr(offset);
nl();
ot("MOV AX,[BP]");
outstr(offset);
outstr(" ;optim111 - 4");
nl();
ptr = ptr1;
}
else
ptr = opti1111(ptr, bump, offset);
}
return ptr;
}
/*
** optimize "++" operators on simple auto variables with no destination
*/
opti1111(ptr, bump, offset) char *ptr, offset[]; int bump; {
ot("INC WORD PTR [BP]");
outstr(offset);
outstr(" ;opti1111 - 1");
nl();
return ptr + bump;
}
/*
** optimize strings beginning
** "\tLEA AX,[BP]xxxx\n\tMOV BX,AX\n\tMOV SI,AX\n\tMOV AX,[SI]\n"
** "\tDEC AX\n\tMOV [BX],AX\n"
*/
optim112(ptr, bump, offset) char *ptr, offset[]; int bump; {
char *ptr1, *ptr2;
ptr1 = ptr + bump; /* skip text already recognized */
ptr2 = ptr; /* save for compare */
if(streq(ptr1, "\tINC AX\n\tMOV SI,AX\n\tMOV AL,[SI]\n")) {
if(ptr1[32]) { /* if not end of expression */
ot("MOV BX,[BP]");
outstr(offset);
nl();
ot("DEC WORD PTR [BP]");
outstr(offset);
nl();
ol("MOV AL,[BX] ;optim112 - 1");
ptr = ptr1 + 32;
}
else
ptr = opti1121(ptr, bump+32, offset);
}
else if(streq(ptr1, "\tINC AX\n")) {
if(ptr1[8]) { /* if not end of expression */
ot("MOV AX,[BP]");
outstr(offset);
nl();
ot("DEC WORD PTR [BP]");
outstr(offset);
outstr(" ;optim112 - 2");
nl();
ptr = ptr1 + 8;
}
else
ptr = opti1121(ptr, bump+8, offset);
}
else if(streq(ptr1, "\tMOV SI,AX\n\tMOV AL,[SI]\n")) {
if(ptr1[24]) { /* if not end of expression */
ot("DEC WORD PTR [BP]");
outstr(offset);
nl();
ot("MOV BX,[BP]");
outstr(offset);
nl();
ol("MOV AL,[BX] ;optim112 - 3");
ptr = ptr1 + 24;
}
else
ptr = opti1121(ptr, bump+24, offset);
}
else {
if(ptr1[0]) { /* if not end of expression */
ot("DEC WORD PTR [BP]");
outstr(offset);
nl();
ot("MOV AX,[BP]");
outstr(offset);
outstr(" ;optim112 - 4");
nl();
ptr = ptr1;
}
else
ptr = opti1121(ptr, bump, offset);
}
return ptr;
}
/*
** optimize "--" operators on simple auto variables with no destination
*/
opti1121(ptr, bump, offset) char *ptr, offset[]; int bump; {
ot("DEC WORD PTR [BP]");
outstr(offset);
outstr(" ;opti1121 - 1");
nl();
return ptr + bump;
}
/*
** optimize strings beginning
** "\tLEA AX,[BP]xxxx\n\tMOV SI,AX\n\tMOV AX,[SI]\n"
*/
optim12(ptr, bump, offset) char *ptr, offset[]; int bump; {
char *ptr1, *ptr2;
ptr1 = ptr + bump; /* skip text already recognized */
ptr2 = ptr; /* save for compare */
if(streq(ptr1, "\tMOV SI,AX\n\tMOV AX,[SI]\n")) {
ot("MOV SI,[BP]");
outstr(offset);
nl();
ol("MOV AX,[SI] ;optim12 - 1");
ptr = ptr1 + 24;
}
else if(streq(ptr1, "\tMOV SI,AX\n\tMOV AL,[SI]\n\tCBW\n\tAND AX,AX\n")) {
ot("MOV SI,[BP]");
outstr(offset);
nl();
ol("CMP BYTE PTR [SI],0 ;optim12 - 2");
ptr = ptr1 + 40;
}
else if(streq(ptr1, "\tMOV SI,AX\n\tMOV AL,[SI]\n")) {
ot("MOV SI,[BP]");
outstr(offset);
nl();
ol("MOV AL,[SI] ;optim12 - 3");
ptr = ptr1 + 24;
}
else {
ot("MOV AX,[BP]");
outstr(offset);
outstr(" ;optim12 - 4");
nl();
ptr = ptr1;
}
return ptr;
}
/*
** optimize strings beginning "\tLEA AX,[BP]xxxx\n\tPUSH AX\n\tLEA AX,[BP]"
*/
optim13(ptr, bump, offset) char *ptr, offset[]; int bump; {
char offset2[20], *ptr1, *ptr2;
ptr1 = ptr + bump; /* skip text already recognized */
ptr2 = offset2;
while((*ptr2++ = *ptr1++) > ' ') ++bump; /* save source from LEA */
*--ptr2 = 0;
++bump;
ptr2 = ptr; /* save for compare */
if(streq(ptr1, "\tMOV SI,AX\n\tMOV AX,[SI]\n\tPOP BX\n\tMOV [BX],AX\n")) {
ot("MOV AX,[BP]");
outstr(offset2);
nl();
ot("MOV [BP]");
outstr(offset);
outstr(",AX ;optim13 - 1");
nl();
ptr = ptr1 + 45;
}
else if(streq(ptr1,
"\tMOV SI,AX\n\tMOV AL,[SI]\n\tCBW\n\tPOP BX\n\tMOV [BX],AL\n")) {
ot("MOV AL,[BP]");
outstr(offset2);
nl();
ol("CBW");
ot("MOV [BP]");
outstr(offset);
outstr(",AL ;optim13 - 2");
nl();
ptr = ptr1 + 50;
}
return ptr;
}
/*
** optimize strings beginning "\tLEA AX,[BP]xxxx\n\tPUSH AX\n\tMOV AX,"
*/
optim14(ptr, bump, offset) char *ptr, offset[]; int bump; {
char offset2[20], *ptr1, *ptr2;
ptr1 = ptr + bump; /* skip text already recognized */
ptr2 = offset2;
while((*ptr2++ = *ptr1++) > ' ') ++bump; /* save source from MOV */
*--ptr2 = 0;
++bump;
ptr2 = ptr; /* save for compare */
if(streq(ptr1, "\tPOP BX\n\tMOV [BX],AX\n")) {
ot("MOV AX,");
outstr(offset2);
nl();
ot("MOV [BP]");
outstr(offset);
outstr(",AX ;optim14 - 1");
nl();
ptr = ptr1 + 21;
}
else if(streq(ptr1, "\tPOP BX\n\tMOV [BX],AL\n")) {
ot("MOV AX,");
outstr(offset2);
nl();
ot("MOV [BP]");
outstr(offset);
outstr(",AL ;optim14 - 2");
nl();
ptr = ptr1 + 21;
}
return ptr;
}
/*
** optimize strings beginning
** "\tLEA AX,[BP]xxxx\n\tPUSH AX\n\tMOV SI,AX\n"
*/
optim15(ptr, bump, offset) char *ptr, offset[]; int bump; {
char *ptr1, *ptr2;
ptr1 = ptr + bump; /* skip text already recognized */
ptr2 = ptr; /* save for compare */
if(streq(ptr1, "\tMOV AX,[SI]\n")) {
ot("LEA SI,[BP]");
outstr(offset);
nl();
ol("PUSH SI");
ol("MOV AX,[SI] ;optim15 - 1");
ptr = ptr1 + 13;
}
else if(streq(ptr1, "\tMOV AL,[SI]\n")) {
ot("LEA SI,[BP]");
outstr(offset);
nl();
ol("PUSH SI");
ol("MOV AL,[SI] ;optim15 - 2");
ptr = ptr1 + 13;
}
return ptr;
}
/*
** optimize strings beginning "\tMOV AX,1\n"
*/
optim3(ptr, bump) char *ptr; int bump; {
char *ptr1, *ptr2;
ptr1 = ptr + bump; /* skip text already recognized */
ptr2 = ptr; /* save for compare */
if(streq(ptr1, "\tJE $+3\n\tDEC AX\n\tAND AX,AX\n\tJNZ $+5\n") |
streq(ptr1, "\tJZ $+3\n\tDEC AX\n\tAND AX,AX\n\tJNZ $+5\n")) {
ol(";optim3 - 1");
ptr = optim9(ptr1+36, "JZ $+");
}
else if(streq(ptr1, "\tJNE $+3\n\tDEC AX\n\tAND AX,AX\n\tJNZ $+5\n") |
streq(ptr1, "\tJNZ $+3\n\tDEC AX\n\tAND AX,AX\n\tJNZ $+5\n")) {
ol(";optim3 - 1B");
ptr = optim9(ptr1+37, "JNZ $+");
}
else if(streq(ptr1, "\tJG $+3\n\tDEC AX\n\tAND AX,AX\n\tJNZ $+5\n")) {
ol(";optim3 - 2");
ptr = optim9(ptr1+36, "JG $+");
}
else if(streq(ptr1, "\tJL $+3\n\tDEC AX\n\tAND AX,AX\n\tJNZ $+5\n")) {
ol(";optim3 - 3");
ptr = optim9(ptr1+36, "JL $+");
}
else if(streq(ptr1, "\tJGE $+3\n\tDEC AX\n\tAND AX,AX\n\tJNZ $+5\n")) {
ol(";optim3 - 4");
ptr = optim9(ptr1+37, "JGE $+");
}
else if(streq(ptr1, "\tJLE $+3\n\tDEC AX\n\tAND AX,AX\n\tJNZ $+5\n")) {
ol(";optim3 - 5");
ptr = optim9(ptr1+37, "JLE $+");
}
return ptr;
}
/*
** optimize strings beginning "\tMOV AX,"
*/
optim4(ptr, bump) char *ptr; int bump; {
char offset[20], *ptr1, *ptr2;
ptr1 = ptr + bump; /* skip text already recognized */
ptr2 = offset;
while((*ptr2++ = *ptr1++) > ' ') ++bump; /* save source from MOV */
*--ptr2 = 0;
++bump;
ptr2 = ptr; /* save for compare */
if(streq(ptr1, "\tINC AX\n\tMOV ")) ptr = optim41(ptr, bump+13, offset);
else if(streq(ptr1, "\tDEC AX\n\tMOV ")) ptr = optim42(ptr, bump+13, offset);
else if(streq(ptr1, "\tMOV BX,")) ptr = optim43(ptr, bump+8, offset);
return ptr;
}
/*
** optimize strings beginning "\tMOV AX,xxxx\n\tINC AX\n\tMOV "
*/
optim41(ptr, bump, offset) char *ptr, offset[]; int bump; {
char *ptr1, *ptr2, *ptr3;
ptr1 = ptr + bump; /* skip text already recognized */
ptr2 = ptr; /* save for compare */
if(streq(ptr1, offset)) {
ptr3 = offset;
while(*ptr3++) {++ptr1; ++bump;} /* skip over value */
if(streq(ptr1, ",AX\n\tDEC AX\n")) {
if(ptr1[12]) {
ot("MOV AX,");
outstr(offset);
nl();
ot("INC ");
outstr(offset);
outstr(" ;optim41 - 1");
nl();
ptr = ptr1 + 12;
}
else ptr = optim411(ptr, bump+12, offset);
}
else if(streq(ptr1, ",AX\n")) {
if(ptr1[4]) {
ot("INC ");
outstr(offset);
nl();
ot("MOV AX,");
outstr(offset);
outstr(" ;optim41 - 2");
nl();
ptr = ptr1 + 4;
}
else ptr = optim411(ptr, bump+4, offset);
}
}
return ptr;
}
/*
** optimize "++" operators on simple static variables with no destination
*/
optim411(ptr, bump, offset) char *ptr, offset[]; int bump; {
ot("INC ");
outstr(offset);
outstr(" ;optim411 - 1");
nl();
return ptr + bump;
}
/*
** optimize strings beginning "\tMOV AX,xxxx\n\tDEC AX\n\tMOV "
*/
optim42(ptr, bump, offset) char *ptr, offset[]; int bump; {
char *ptr1, *ptr2, *ptr3;
ptr1 = ptr + bump; /* skip text already recognized */
ptr2 = ptr; /* save for compare */
if(streq(ptr1, offset)) {
ptr3 = offset;
while(*ptr3++) {++ptr1; ++bump;} /* skip over value */
if(streq(ptr1, ",AX\n\tINC AX\n")) {
if(ptr1[12]) {
ot("MOV AX,");
outstr(offset);
nl();
ot("DEC ");
outstr(offset);
outstr(" ;optim42 - 1");
nl();
ptr = ptr1 + 12;
}
else ptr = optim421(ptr, bump+12, offset);
}
else if(streq(ptr1, ",AX\n")) {
if(ptr1[4]) {
ot("DEC ");
outstr(offset);
nl();
ot("MOV AX,");
outstr(offset);
outstr(" ;optim42 - 2");
nl();
ptr = ptr1 + 4;
}
else ptr = optim421(ptr, bump+4, offset);
}
}
return ptr;
}
/*
** optimize "--" operators on simple auto variables with no destination
*/
optim421(ptr, bump, offset) char *ptr, offset[]; int bump; {
ot("DEC ");
outstr(offset);
outstr(" ;optim421 - 1");
nl();
return ptr + bump;
}
/*
** optimize strings beginning "\tMOV AX,xxxx\n\tMOV BX,"
*/
optim43(ptr, bump, offset) char *ptr, offset[]; int bump; {
char offset2[20], *ptr1, *ptr2;
ptr1 = ptr + bump; /* skip text already recognized */
ptr2 = offset2;
while((*ptr2++ = *ptr1++) > ' ') ++bump; /* save source from MOV */
*--ptr2 = 0;
++bump;
ptr2 = ptr; /* save for compare */
if(streq(ptr1, "\n\tADD AX,BX\n\tMOV SI,AX\n\tMOV AX,[SI]\n")) {
ot("MOV BX,");
outstr(offset);
nl();
ot("ADD BX,");
outstr(offset2);
nl();
ol("MOV AX,[BX] ;optim43 - 1");
ptr = ptr1 + 36;
}
return ptr; /* "MOV BX," may be separately optimizable */
}
/*
** optimize strings beginning "\tPUSH AX\n\tMOV AX,"
*/
optim5(ptr, bump) char *ptr; int bump; {
char offset[20], *ptr1, *ptr2;
ptr1 = ptr + bump; /* skip text already recognized */
ptr2 = offset;
while((*ptr2++ = *ptr1++) > ' ') ++bump; /* save source from MOV */
*--ptr2 = 0;
++bump;
ptr2 = ptr; /* save for compare */
if(streq(ptr1, "\tPOP BX\n\tADD AX,BX\n")) {
ot("ADD AX,");
outstr(offset);
outstr(" ;optim5 - 1");
nl();
ptr = ptr1 + 19;
}
else if(streq(ptr1, "\tPOP BX\n\tSUB AX,BX\n\tNEG AX\n")) {
ot("SUB AX,");
outstr(offset);
outstr(" ;optim5 - 2");
nl();
ptr = ptr1 + 27;
}
else if(streq(ptr1, "\tPOP BX\n\tSUB AX,BX\n")) {
ot("SUB AX,");
outstr(offset);
nl();
ol("NEG AX ;optim5 - 3");
ptr = ptr1 + 19;
}
else if(streq(ptr1, "\tPOP BX\n\tCMP BX,AX\n")) {
ot("CMP AX,");
outstr(offset);
outstr(" ;optim5 - 4");
nl();
ptr = ptr1 + 19;
}
else if(streq(ptr1, "\tPOP BX\n\tXCHG AX,BX\n")) {
ot("MOV BX,");
outstr(offset);
outstr(" ;optim5 - 5");
nl();
ptr = ptr1 + 20;
}
else if(streq(ptr1, "\tPOP BX\n")) {
ol("MOV BX,AX");
ot("MOV AX,");
outstr(offset);
outstr(" ;optim5 - 6");
nl();
ptr = ptr1 + 8;
}
return ptr;
}
/*
** optimize strings beginning "\tPUSH AX\n\tLEA AX,[BP]"
*/
optim6(ptr, bump) char *ptr; int bump; {
char offset[20], *ptr1, *ptr2;
ptr1 = ptr + bump; /* skip text already recognized */
ptr2 = offset;
while((*ptr2++ = *ptr1++) > ' ') ++bump; /* save offset from LEA */
*--ptr2 = 0;
++bump;
ptr2 = ptr; /* save for compare */
if(streq(ptr1, "\tMOV SI,AX\n\tMOV AX,[SI]\n\tPOP BX\n")) {
ol("MOV BX,AX");
ot("MOV AX,[BP]");
outstr(offset);
outstr(" ;optim6 - 1");
nl();
ptr = ptr1 + 32;
}
return ptr;
}
/*
** optimize strings beginning "\tMOV BX,DX\n\tPOP BX\n"
*/
optim7(ptr, bump) char *ptr; int bump; {
ol(";optim7 - 1");
return ptr + 11; /* just skip over the useless part */
}
/*
** optimize strings beginning "\tMOV BX,"
*/
optim8(ptr, bump) char *ptr; int bump; {
char offset[20], *ptr1, *ptr2;
ptr1 = ptr + bump; /* skip text already recognized */
ptr2 = offset;
while((*ptr2++ = *ptr1++) > ' ') ++bump; /* save offset from LEA */
*--ptr2 = 0;
++bump;
ptr2 = ptr; /* save for compare */
if(streq(ptr1, "\tADD AX,BX\n")) {
ot("ADD AX,");
outstr(offset);
outstr(" ;optim8 - 1");
nl();
ptr = ptr1 + 11;
}
else if(streq(ptr1, "\tSUB AX,BX\n")) {
ot("SUB AX,");
outstr(offset);
outstr(" ;optim8 - 2");
nl();
ptr = ptr1 + 11;
}
return ptr;
}